# -*-coding:utf-8 -*-
# @Time: 2023/3/29 11:28
# @Author: cuishuohao
# @File: demo_teacher
# @Software: PyCharm

# (1)首先生成随机的分类数据:
import numpy as np
import matplotlib.pyplot as plt

# 构造二分类数据库构造过程与逻辑回归实例一致
np.random.seed(0)
Num = 100  # 100个样本
x_1 = np.random.normal(6, 1, size=(Num))
x_2 = np.random.normal(3, 1, size=(Num))
y = np.ones(Num) * (-1)
c_n1 = np.array([x_1, x_2, y])  # 构造-1分类数据
x_1 = np.random.normal(3, 1, size=(Num))
x_2 = np.random.normal(6, 1, size=(Num))
y = np.ones(Num)
c_1 = np.array([x_1, x_2, y])  # 构造+1分类数据
c_1 = c_1.T
c_n1 = c_n1.T
plt.scatter(c_1[:, 0], c_1[:, 1], marker='+', label='1')
plt.scatter(c_n1[:, 0], c_n1[:, 1], marker='.', label='-1')
plt.legend()
plt.show()

# (2)将数据分为训练集和测试集
# 建立数据集，分训练集和测试集
All_data = np.concatenate((c_1, c_n1))
print(All_data.shape)  # 所有数据的形状
np.random.shuffle(All_data)
train_data_X = All_data[:150, :2]
train_data_y = All_data[:150, -1].reshape(150, 1)
test_data_X = All_data[150:, :2]
test_data_y = All_data[150:, -1].reshape(50, 1)
print(train_data_X.shape, train_data_y.shape, test_data_X.shape, test_data_y.shape)

# (3)构建感知机模型
# 初始化参数为0
W = np.zeros((2, 1))  # 2为特征的个数，我们这里只有两个特征
b = 0
T = 10  # 最大迭代次数
train_data = np.concatenate((train_data_X, train_data_y), axis=1)
# 训练模型
for t in range(T):
    np.random.shuffle(train_data)  # 对训练集中的样本随机排序
    for i in range(len(train_data)):  # N=len(train_data)为训练集中的样本数
        # 选取第i个样本
        tmp = train_data[i][-1] * np.dot(W.T, train_data[i][:2].reshape(2, 1)) + b

        if tmp <= 0:
            W = W + (train_data[i][-1] * train_data[i][:2]).reshape(2, 1)
            b = b + train_data[i][-1]

# (4)显示分类模型
# 显示分类模型
x = np.arange(1, 9)
y = -(W[0] * x + b) / W[1]
plt.plot(x, y)
plt.scatter(c_1[:, 0], c_1[:, 1], marker='+', label='1')
plt.scatter(c_n1[:, 0], c_n1[:, 1], marker=".", label='-1')
plt.legend()
plt.show()
